﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace IcqSharp
{
    public class CloseChannelHandler //: ChannelHandler
    {
        public static void Handle(MemoryStream stream)
        {
            // parse reply, prepare reconnection
            if (!Session.LoggedIn && stream.Length > 0 && !Session.NewServerReady)
                HandleLoginReply(stream);

            // handle server migration
            if (Session.IsMigrating) ; // HandleMigration();

            // connect
            if ((!Session.LoggedIn || Session.IsMigrating) && Session.NewServerReady)
            {
                //Session.ProcessMessagesThread = new Thread(new ThreadStart(Session.ProcessMessages));
                //Session.ProcessMessagesThread.Start();

                Log.Write("Reconnecting to new server");

                Session.ConnectToNewServer();
                if (Session.client.Connected)
                {
                    //new Thread(new ThreadStart(Session.ProcessMessages)).Start();
                }
                else
                {
                    // Connecting failed
                    if (Session.IsMigrating) ; // Unable to connect to migrated ICQ communication server
                    else ; // Unable to connect to ICQ communication server

                    Session.Status = IcqStatus.Offline;
                    Session.IsMigrating = false;
                }

                Session.NewServerReady = false;

                return;
            }

            // read chain
            var chain = new TLVChain(stream);
            if (chain != null)
            {
                // TLV 9 errors (runtime errors?)
                var Error = chain.GetWord(0x09, 1);
                if (Error != 0)
                {
                    Session.Status = IcqStatus.Offline;
                    ; //HandleRuntimeError(wError);
                }
            }

            // Server closed connection on error, or sign off
            ; // NetLib_CloseConnection(&hServerConn, TRUE);
        }

        public static void HandleLoginReply(MemoryStream stream)
        {
            Log.Write("Got  Authorization.LoginReply");

            var chain = new TLVChain(stream);
            if (chain == null)
            {
                // Error: Missing chain on close channel
                Debugger.Break(); return;
            }

            // imitate icq5 behaviour
            new Packet(Channel.Close).Send();
            Log.Write("Sent  Close");

            // TLV 8 errors (signon errors?)
            var Error = chain.GetWord(0x08, 1);
            if (Error != 0)
            {
                var error = (SignonError?)Error;

                Debugger.Break();

                // we return only if the server did not gave us cookie (possible to connect with soft error)
                if (chain.GetLength(0x06, 1) == 0)
                {
                    //disposeChain(&chain);
                    //SetCurrentStatus(ID_STATUS_OFFLINE);
                    //icq_serverDisconnect(FALSE);
                    Debugger.Break();
                    return; // Failure
                }
            }

            // We are in the login phase and no errors were reported.
            // Extract communication server info.
            Session.NewServer = chain.GetString(0x05, 1);
            Session.NewServerSSL = chain.GetNumber(0x8E, 1) != 0;
            Session.CookieData = chain.GetData(0x06, 1);

            if (Session.NewServer == null || Session.CookieData == null)
            {
                // You could not sign on because the server returned invalid data. Try again.
                Debugger.Break(); return;
            }

            // Authenticated
            Session.NewServerReady = true;
        }

    }
}
